package com.zjc.agent.ai.tools;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import dev.langchain4j.agent.tool.P;
import dev.langchain4j.agent.tool.Tool;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.FileCopyUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

// 引入Caffeine缓存相关类
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;

/**
 * 天气查询工具
 */
@Slf4j
public class WeatherTool {

    private final HttpClient httpClient = HttpClient.newBuilder()
            .connectTimeout(Duration.ofSeconds(10))
            .build();

    private static final String API_URL = "http://t.weather.itboy.net/api/weather/city/";
    
    // 城市代码缓存
    private static final Map<String, String> CITY_CODE_MAP = new HashMap<>();
    
    // 天气信息缓存，设置缓存最大数量为100，过期时间为30分钟
    private static final Cache<String, String> WEATHER_CACHE = Caffeine.newBuilder()
            .maximumSize(100)
            .expireAfterWrite(30, TimeUnit.MINUTES)
            .build();
    
    // 静态初始化块，加载城市代码数据
    static {
        try {
            InputStream inputStream = WeatherTool.class.getClassLoader().getResourceAsStream("docs/city-codes.csv");
            if (inputStream != null) {
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                String line;
                // 跳过标题行
                reader.readLine();
                while ((line = reader.readLine()) != null) {
                    String[] parts = line.split(",");
                    if (parts.length == 2) {
                        CITY_CODE_MAP.put(parts[0].trim(), parts[1].trim());
                    }
                }
                reader.close();
            }
        } catch (Exception e) {
            log.error("加载城市代码数据失败", e);
        }
    }
    
    @Tool(name = "weatherQuery", value = """
    根据城市名称查询天气。
    输入城市名称，自动匹配城市代码并查询天气信息。
    """)
    public static String getWeather(@P(value = "城市名称") String city) {
        // 先从缓存中获取
        String cachedWeather = WEATHER_CACHE.getIfPresent(city);
        if (cachedWeather != null) {
            log.info("从缓存中获取城市'{}'的天气信息", city);
            return cachedWeather;
        }
        
        // 查找城市代码
        String code = CITY_CODE_MAP.get(city);
        if (code == null) {
            // 尝试模糊匹配
            Optional<Map.Entry<String, String>> matchedEntry = CITY_CODE_MAP.entrySet().stream()
                    .filter(entry -> entry.getKey().contains(city) || city.contains(entry.getKey()))
                    .findFirst();
            
            if (matchedEntry.isPresent()) {
                code = matchedEntry.get().getValue();
            } else {
                return "未找到城市'" + city + "'的代码，请确认城市名称是否正确";
            }
        }
        
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(API_URL + code)
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("HTTP " + response.code());
            }
            if (response.body() != null) {
                String result = response.body().string();
                // 将结果存入缓存
                WEATHER_CACHE.put(city, result);
                return result;
            }
            return "查询失败";
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }



    public static void main(String[] args) {
        WeatherTool weatherTool = new WeatherTool();
//        System.out.println(weatherTool.searchWeatherInfo("上海", "2025-08-04"));
        System.out.println(WeatherTool.getWeather("上海"));
        System.out.println(WeatherTool.getWeather("上海"));

    }
}